feat(cl2k): mirror the artwork horizontally - #579
Conversation
A Mirror toggle on the poster, square-art and background-art makers flips the artwork left-to-right — for backdrops whose subject faces out of frame. The flip lands at the END of framing, not on the source bytes, and that placement is the whole design. The AI text-removal mask and the extend outpaint are built in source space, so flipping the source first would put every brush stroke on the wrong side of the picture; the logo and label are composited after the artwork, so flipping the finished poster would render the season band backwards. _framed_inset_base and render_framed_art are the two points where framing is finished and nothing else is drawn yet, so both flop there. Applying it last also means no coordinate is re-mapped: the framer keeps showing the source as it is, and toggling Mirror leaves the crop box and focal point exactly where they were. The .psd export follows the poster (both go through frame_backdrop) and the season batch carries the flag, so a bulk run matches its preview.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughThe PR adds a ChangesCL2K Mirror Rendering
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to The optional Mirror control changes artwork orientation while preserving existing behavior by default and keeping labels readable. No actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Frontend
participant FastAPIEndpoint
participant cl2k_maker
participant render_cl2k
Frontend->>FastAPIEndpoint: submit mirror setting
FastAPIEndpoint->>cl2k_maker: forward mirror value
cl2k_maker->>render_cl2k: render artwork with mirror
render_cl2k-->>FastAPIEndpoint: return mirrored asset
FastAPIEndpoint-->>Frontend: return preview or generated asset
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
CodeRabbit, against the repo's own path instructions: these carried implementation history and rationale rather than a one-or-two-line what/gotcha. The "why we bundled it" argument belongs in the PR body, where it already is. Kept the gotchas that stop someone breaking things — the wire format stays flat, a partial crop is ignored, and mirror lands at the end of framing because the AI mask is built in source space. Dropped the essays around them. Also trims the same violation in _framed_inset_base, which I wrote in #579 and which the diff-scoped review therefore never saw.
…582) focus_x / fit_mode / crop / v_pos / zoom / mirror were six parameters threaded through four layers — 41 occurrences across three backend files, so adding the sixth (mirror, #579) cost 24 mechanical signature edits and nothing else. They are now one frozen geometry.Framing, making the seventh knob a one-line change. The wire format is unchanged: the frontend still posts flat scalars, every request model is byte-identical, and _framing(req) at the endpoint boundary is the single place that shape becomes the object. No frontend or config change. The AI-extend reset becomes dataclasses.replace(), which keeps mirror and focus_x exactly as the old four-way tuple assignment did — with a test pinning that mirror survives it, since clearing it would silently un-flip every extended poster. Verified behaviour-preserving rather than assumed: 13 framings across all three render entry points, compared by pixel signature against main — 39 renders, all identical.
Summary
Adds a Mirror toggle to the CL2K poster, square-art and background-art makers that flips the artwork left-to-right — for backdrops whose subject faces out of frame, or whose composition sits on the wrong side for the logo.
Related issue
N/A — user request.
Type of change
Where the flip lands, and why it matters
At the end of framing, not on the source bytes —
_framed_inset_baseandrender_framed_artare the two points where framing is finished and nothing else has been drawn yet, so bothflop()there. Two things forced that placement:modules/cl2k_maker.py—fit_extend_canvas, thentext_removal.remove_text). Flipping the source first would put every brush stroke, and every Detect/Tighten result, on the wrong side of the picture.A useful consequence: because the flip is last, no coordinate is re-mapped. The framer keeps showing the source as it is, and toggling Mirror leaves the crop box and focal point exactly where they were.
Both callers of
_framed_inset_baseinherit it, so the.psdexport stays pixel-identical to the poster beside it, and the season batch carries the flag so a bulk run matches its preview. The clear-logo maker deliberately does not get the toggle — a mirrored wordmark is just broken art.Testing
tests/test_cl2k_mirror.py(24 tests, new):.psdPOSTER frame;focus_x=0.2, v_pos=0.3, zoom=1.6the mirrored frame equals the flop of the unmirrored one, compared losslessly onframe_backdrop's PNG;TestClientPOST that renders real mirrored pixels over HTTP;mirrordefaults toFalseon all four request models, so nothing already made re-renders differently.Mutation-tested: dropping either
flop(), flipping the whole poster instead of just the art, dropping one API forward, dropping one module→renderer forward, or removing the model field each fails the suite. Control run green.Full suites:
pytest2123 passed;ruff check .clean;npm run lintclean (one pre-existing warning, unrelated);prettier --check srcclean;npm run buildclean; frontend vitest 78 passed.Screenshots
Rendered before/after of the same source (subject swaps sides;
MIRROR DEMOandSEASON ONEstay put and readable) — attached in review.Checklist
cd frontend && npm run build)DAPSreferences introducedfeat(cl2k):commitSummary by CodeRabbit
New Features
Bug Fixes